/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 */

package com.huawei.saashousekeeper.interceptor;

import com.huawei.saashousekeeper.config.binding.SchemaBindingStrategy;
import com.huawei.saashousekeeper.context.TenantContext;
import com.huawei.saashousekeeper.exception.RoutingException;

import lombok.extern.log4j.Log4j2;

import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.springframework.beans.factory.annotation.Autowired;

import java.sql.Connection;
import java.util.Locale;
import java.util.Optional;

/**
 * mybatis拦截，获取connection
 *
 * @since 2022-02-14
 */
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
@Log4j2
public class MybatisInterceptor implements Interceptor {
    @Autowired
    private SchemaBindingStrategy schemaBindingStrategy;

    @Override
    public Object intercept(Invocation invocation) throws Exception {
        String domain = TenantContext.getDomain();

        // 当前租户绑定的数据源未开通schema隔离，不切换schema
        if (!TenantContext.isSchemaIsolation()) {
            log.warn("Schema route configuration is not enabled for tenant {} and routes to the default schema", domain);
            return invocation.proceed();
        }

        String catalog = schemaBindingStrategy.getSchema(domain);

        // 当租户绑定的数据源开通了schema隔离时，如果schema为空，则直接抛出异常
        Optional.ofNullable(catalog)
            .orElseThrow(() -> new RoutingException(String.format(Locale.ENGLISH,
                "The schema isolation function is enabled for the data source bound to tenant %s, but no schema is bound",
                domain)));
        log.warn("{} select schema {}", domain, catalog);
        Connection conn = (Connection) invocation.getArgs()[0];
        conn.setCatalog(catalog);
        return invocation.proceed();
    }
}
